package org.idea.dao.impl;

import org.idea.dao.BankDao;
import org.idea.util.DbUtil;

import java.sql.*;

/**
 * @Author zqx
 * @Date 2023-10-12
 */
public class BankDaoImpl implements BankDao {
    /**
     * 使用 Java 中的 JDBC 调用数据库定义的存储过程 - 区别 CRUD
     * @param outName
     * @param inName
     * @param money
     * @return
     */
    @Override
    public int trans1(String outName, String inName, double money) {
        int r = 0;
        // 第一：定义调用存储过过程的SQL语句,语法如下：
        // {call 存储过程名称(参数占位符1,...,参数占位符n)}
        String sql = "{call zhuan_zhang(?,?,?,?)}";

        // 第二：获取连接对象
        Connection conn = DbUtil.getConnection();
        CallableStatement cstmt = null;
        ResultSet rst = null;

        try {
            // 第三：预编译SQL语句，返回CallableStatement对象
            cstmt = conn.prepareCall(sql);

            // 第四：参数处理
            // 输入参数：必须进行数据的填充（同PreparedStatement）
            // 输出参数：注册输出参数的数据类型，语法如下：
            // cstmt.registerOutParameter(下标索引, Types.XXX) ;
            cstmt.setDouble(1, money);
            cstmt.setString(2, inName);
            cstmt.setString(3, outName);
            cstmt.registerOutParameter(4, Types.INTEGER);

            // 第五：执行SQL语句
            cstmt.execute();
            // cstmt.executeQuery
            // cstmt.executeUpdate

            // 第六：获取输出参数，语法如下：
            // CallableStatement对象.getXxx(输出参数占位符索引)
            r = cstmt.getInt(4);

            // 第七：获取查询的结果集
            // Result rst = CallableStatement对象.getResultSet() ;
        } catch (SQLException e) {
            r = -1 ;
        } finally {
            // 第八：关闭对象
            DbUtil.close(conn, cstmt, null);
        }
        return r;
    }

    private void update(String username,double money,Connection conn) {
        String sql = "update bank set currentMoney=currentMoney + ? where customerName=?" ;
        try {
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setDouble(1,money);
            pstmt.setString(2,username);
            pstmt.executeUpdate() ;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int trans2(String outName, String inName, double money) {
        int r = 0 ;
        Connection conn = DbUtil.getConnection();
        try {
            // 设置事务 - 手动提交 - 注意：转出和转入必须使用同一个连接对象
            conn.setAutoCommit(false);

            // 转出
            update(outName,-money,conn);

            // 转入
            update(inName,money,conn);

            r = 1;
            // 提交事务
            conn.commit();
        } catch (SQLException e) {
            if(conn!=null) {
                try {
                    // 回滚事务
                    conn.rollback();
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
            }
        } finally {
            DbUtil.close(conn,null,null);
        }
        return r;
    }
}
